#ifndef  SHINY_EVENTMANAGER_HPP
# define SHINY_EVENTMANAGER_HPP

# include <SFML/Window.hpp>
# include <SFML/Graphics.hpp>
# include <list>
# include "control.hpp"
# include "observatory.hpp"
# define IS_MOUSE_EVENT(event) (event.Type == sf::Event::MouseButtonPressed || event.Type == sf::Event::MouseButtonReleased || event.Type == sf::Event::MouseWheelMoved || event.Type == sf::Event::MouseMoved)

namespace Shiny
{
  class EventManager
  {
    static EventManager* _instance;
  public:
    EventManager(void);
    static EventManager* Get(void);

    class Mouse
    {
    public:
      struct Event
      {
	Event(sf::Event event);
	sf::Vector2f position;
	sf::Event    event;
      };
      
      class Listener
      {
      public:
	virtual bool mouseEvent(Event) = 0;
	virtual void ExpectedMouseRelease(void) {}
	virtual void ExpectedMouseMove(void)    {}
      };

      typedef std::list<Listener*> Listeners;

      Mouse();
      bool      ReceiveEvent(const sf::Event);
      void      AddListener(Listener*);
      void      DelListener(Listener*);
      void      SetFocus(Listener*);
      
      void      ExpectMouseRelease(Listener*);
      void      ExpectMouseMove(Listener*);

    private:
      void      HandleExpectedEvents(const sf::Event);
      
      Listeners _listeners;
      Listener* _waitingButtonRelease;
      Listener* _waitingMouseMove;
    };

    bool            Run(sf::RenderWindow&);
    Mouse&          MouseManager(void) { return (_mouseManager);   }
    ControlManager& Controls(void)     { return (_controlManager); }
    
    Observatory::Signal<sf::Event>  WidgetsEventObserver;

  private:
    Mouse                          _mouseManager;
    ControlManager                 _controlManager;
  };
}

#endif